<template>
  <div class="terminal">
    <el-row :gutter="10">
    <!--  左边内容-->
    <el-col :span="4" class="tree-component" >
      <div style="display: flex; justify-content: left">
        <el-button icon="el-icon-caret-left" size="large" type="text" @click="back">返回</el-button>
      </div>
      <el-tag class="tag-style">终端列表</el-tag>
      <el-scrollbar height="calc(100vh - 110px)">
        <el-tree
          class="filter-tree"
          :data="serverList"
          :props="treeProps"
          default-expand-all
          :expand-on-click-node="false"
          @node-click="handleNodeClick"
          :highlight-current="true"
          node-key="id"
          :current-node-key="currentNodekey"
          ref="tree"
        >
        <template v-slot="{ node, data }">
          <el-scrollbar>
          <span class="bold-node">
            {{ data.name }}
          </span>
          <span style="margin-left: 5px;font-size: 12px">
            {{ data.host_ip }}
          </span>
          </el-scrollbar>
        </template>
        </el-tree>
      </el-scrollbar>

    </el-col>
    <!--  右边内容-->
    <el-col :span="20">
        <div id="terminal" ref="terminal"></div>
        <div style="display: flex; justify-content: center;margin-top: 25px">
          <el-button type="primary" @click="terminal_close">关闭终端连接</el-button>
        </div>
    </el-col>
  </el-row>
  </div>
</template>

<script>
import { Terminal } from 'xterm';
import 'xterm/css/xterm.css';
import {mapMutations, mapState} from "vuex";
import { config } from '/src/api/index.js';
export default {
  data() {
    return {
      serverList:[],
      host_ip: '',
      host_port: '',
      sys_user_name: '',
      sys_user_passwd: '',
      term: null,
      ws: null,
      treeProps: {
        children: 'children',
        label: 'label'
      },
      currentNodekey: [],
    };
  },
  computed: {
    ...mapState({
      server: state => state.server,
      pro: state => state.pro,

    })
  },
  mounted() {
    // this.initTerminal();
  },
  methods: {
    ...mapMutations(['servers','clearServers']),
    handleNodeClick(data) {
      this.getServer(data.id)
    },

    initTerminal() {
      // 清理之前的终端实例和 WebSocket 连接
      if (this.term) {
        this.term = null;
      }
      if (this.ws) {
        this.ws.close();
        this.ws = null;
      }
      this.term = new Terminal({
        allowTransparency: true,
        cursorBlink: true,
        cursorStyle: 'underline',
        rows: 40,
        cols: 150,
        theme: {
          background: '#000000',
          cursor: '#ffffff',
          foreground: '#67c23a'
        }
      });

      // Make sure the terminal container is empty before opening a new instance
      const terminalContainer = this.$refs.terminal;
      terminalContainer.innerHTML = ''; // Clear previous content
      this.term.open(terminalContainer);

      const xtermElement = this.term.element;
      xtermElement.style.padding = '10px';

      this.term.write('\x1B[1;3;33m正在连接过程中请勿随意切换服务器终端...\x1B[0m\r\n');

      // Connect to WebSocket
      const wsURL = `ws://${config.baseURL.split('//')[1]}/asset/terminal/?host_ip=${this.host_ip}&host_port=${this.host_port}&sys_user_name=${this.sys_user_name}&sys_user_passwd=${this.sys_user_passwd}`;
      this.ws = new WebSocket(wsURL);

      // WebSocket event listeners
      this.ws.onopen = () => {
        this.term.onData(data => {
          const send_data = JSON.stringify({
            flag: 'entered_key',
            entered_key: data,
            cols: null,
            rows: null
          });
          if (this.ws.readyState === WebSocket.OPEN) {
            try {
              this.ws.send(send_data);
            } catch (e) {
              // 捕获并忽略发送过程中可能出现的错误
              console.log('WebSocket send error:', e);
            }
          }
        });

        this.ws.onmessage = event => {
          this.term.write(event.data);
        };

        // this.ws.onclose = event => {
        //   // this.term.write('\n\r\x1B[1;3;31m{{event.data}}\x1B[0m');
        // };
      };

      this.ws.onerror = event => {
        console.log('WebSocket error:', event);
      };

      // Resize event handler
      window.addEventListener('resize', () => {
        const { cols, rows } = this.getBoxSize();
        const send_data = JSON.stringify({
          flag: 'resize',
          cols: cols,
          rows: rows
        });
        if (this.ws.readyState === WebSocket.OPEN) {
          try {
            this.ws.send(send_data);
          } catch (e) {
            // 捕获并忽略发送过程中可能出现的错误
            console.log('WebSocket send error:', e);
          }
        }
        this.term.resize(cols, rows);
      });
    },


    getBoxSize() {
      const init_width = 9;
      const init_height = 18;

      // Check if this.$refs.terminal is defined
      if (!this.$refs.terminal) {
        return { cols: 80, rows: 24 }; // Return default values or handle appropriately
      }

      const windows_width = this.$refs.terminal.clientWidth;
      const windows_height = window.innerHeight;
      return {
        cols: Math.floor(windows_width / init_width),
        rows: Math.floor(windows_height / init_height)
      };
    },

    terminal_close() {
      this.ws.close();

      this.ws.onclose = event => {
        this.term.write('\n\r\x1B[1;3;31m连接关闭！\x1B[0m');
      };
    },
    back() {
      this.ws.close();
      this.clearServers()
      window.history.back();
    },

    async getServer(id) {
     const response =await this.$api.getServer(id)
     if (response.status ===200){
				this.host_ip = response.data.host_ip;
				this.host_port = response.data.host_port;
				this.sys_user_name = response.data.sys_user_name;
				this.sys_user_passwd = response.data.sys_user_passwd;
			}
     this.initTerminal();
    },
    async getServerList() {
     const response =await this.$api.getServers(this.pro.id,1)
     if (response.status ===200){
				this.serverList = response.data.result;
				this.getServer(this.server);
				this.currentNodekey=this.server;
        this.$nextTick(() => {
        this.$refs.tree.setCurrentKey(this.currentNodekey); //一定要加这个选中了否则样式没有出来
        });
			}
    },

  },
  created() {
    this.getServerList();
  }
};
</script>

<style scoped>
.terminal {
  margin: 10px;
}

.tree-component {
  box-shadow: 5px 0 5px rgba(0, 0, 0, 0.10); /* 添加此样式来设置阴影 */
}
.filter-tree {
  margin-top: 10px;
  padding-right:0px;
}
.tree-component[data-v-1b4274da] {
    width: 300px;
    padding-right: 0px;
    box-shadow: 5px 0 5px rgba(0, 0, 0, 0.06);
}
.bold-node {
  font-weight: bold;
  font-size: 13px
}

.tag-style {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  font-size: 15px;
}
</style>
